package com.ruoyi.app.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.app.util.CompressUtils;
import com.ruoyi.bizsys.domain.*;
import com.ruoyi.bizsys.mapper.CustContactsRelativeMapper;
import com.ruoyi.bizsys.service.*;
import com.ruoyi.bizsys.utils.BizConstants;
import com.ruoyi.business.Vo.RulePremiseVo;
import com.ruoyi.business.common.riskRule.LoanRule;
import com.ruoyi.business.common.riskRule.RulePremiseService;
import com.ruoyi.business.service.IRaiseLimitService;
import com.ruoyi.business.util.PhoneUtil;
import com.ruoyi.common.VersionUtils;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.enums.RspEnmu;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.Func;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author cyh
 * @date 2022/5/20 6:58 下午
 */
@Service
@Slf4j
public class ContactService {


    @Autowired
    private RulePremiseService premiseService;

    @Autowired
    private IApplyContactsService iApplyContactsService;

    @Autowired
    ICustAndonLogService iCustAndonLogService;

    @Autowired
    LoanRule loanRule;

    @Autowired
    IAppDeviceContactapplistRelativeService iAppDeviceContactapplistRelativeService;

    @Autowired
    IRaiseLimitService raiseLimitService;

    @Autowired
    CustContactsRelativeMapper custContactsRelativeMapper;

    @Autowired
    IDeviceContactsService iDeviceContactsService;

    @Autowired
    IDeviceUserService iDeviceUserService;

    @Autowired
    IDeviceAppListService iDeviceAppListService;

    @Autowired
    IAppDeviceInfoService iAppDeviceInfoService;

    @Autowired
    private IAppUserService appUserService;


    @Autowired
    private IAppUserScoreService appUserScoreService;


    private static final String SAVE_CONTACTS_ACTION = "saveContact";

    @Autowired
    private IAppUserContactsService appUserContactsService;
    private static final String REGISTER_ACTION = "register";


    //获取通讯录是否已授权
    private boolean getHasPhoneContacts(Long userId) {
        AppUserContacts appUserContacts = new AppUserContacts();
        appUserContacts.setUserId(userId);
        List<AppUserContacts> userContactsList = appUserContactsService.selectAppUserContactsList(appUserContacts);
        if (userContactsList.size() > 0) {
            return true;
        }
        return false;
    }

    //通讯录保存
    public JSONObject userContacts(JSONObject dataJson) {
        JSONObject rsp = new JSONObject();

        //查找用户
        AppUser userQuery = new AppUser();
        userQuery.setUserUuid(dataJson.get("userId").toString());
        List<AppUser> inviteCodeList = appUserService.selectAppUserList(userQuery);
        if (inviteCodeList.size() < 1) {
            throw new BusinessException(RspEnmu.USER_NOT_EXIST);
        }
        AppUser user = inviteCodeList.get(0);

        //是否1已授权过通讯录
        boolean hasPhoneContacts = this.getHasPhoneContacts(user.getUserId());
        boolean saveSuccess = false;
        //保存通讯录
        String batchNo = DateFormatUtils.format(new Date(), "yyyyMMddHHmmss");
        JSONArray dataJsonArr = dataJson.getJSONArray("bookList");
        for (int i = 0; i < dataJsonArr.size(); i++) {
            JSONObject tempObject = dataJsonArr.getJSONObject(i);
            if (null == tempObject.get("phone") || StringUtils.isBlank(tempObject.get("phone").toString())) {
                continue;
            } else {
                String phone = tempObject.getString("phone");
                if (phone.length() < 10) {
                    continue;
                }

                String phoneNumber = formatPhone(phone);

                AppUserContacts appUserContacts = new AppUserContacts();
                appUserContacts.setUserId(user.getUserId());
                appUserContacts.setBatchNo(batchNo);
                if (null == tempObject.get("contactName") || StringUtils.isBlank(tempObject.get("contactName").toString())) {
                    appUserContacts.setCallName(tempObject.get("phone").toString());
                } else {
                    appUserContacts.setCallName(StringUtils.removeNonBmpUnicodes(tempObject.get("contactName").toString()));
                }
                appUserContacts.setPhone(phoneNumber);
                if (null != tempObject.get("countryCode") || StringUtils.isNotBlank(tempObject.get("countryCode").toString())) {
                    appUserContacts.setCountryCode(tempObject.get("countryCode").toString());
                }
                appUserContactsService.insertAppUserContacts(appUserContacts);
                saveSuccess = true;
            }
        }

        //积分增加
        if (!hasPhoneContacts && saveSuccess) {
            //更新注册积分
            this.updateUserScore(user.getUserId(), SAVE_CONTACTS_ACTION, -1000L);
        }

        return rsp;
    }

    /**
     * 通讯录授权
     *
     * @param dataJson
     * @return
     */
    @Async("threadPoolTaskExecutor")
    public JSONObject custContactsLock(JSONObject dataJson, String userId, String custNo, String appVersion) {

        //原代码就把uuid当成custNo传入，暂时维持不变
        //String userId = getAppUser().getUserUuid();
        //String actionType = dataJson.getString("actionType");
        String applyNo = dataJson.getString("applyNo");
        //String applyNo = getApplyNo(custNo,dataJson.getString("actionType"));

        if (StringUtils.isNotBlank(applyNo)) {
            long start = System.currentTimeMillis();
            saveContactsDB(dataJson, applyNo, userId, custNo, appVersion);
            long end = System.currentTimeMillis();
            log.info("通讯录入库耗时：" + (end - start) + " ms");
        }

        return new JSONObject();
    }

    /**
     * V228通讯录授权
     *
     * @param dataJson
     * @return
     */
    @Async("threadPoolTaskExecutor")
    public void custContactsV228(JSONObject dataJson, String userId,String custNo, String appVersion) {

        String fingerprint = dataJson.getString("fingerprint");

        //查找七天内是否有上传通讯录数据
        String contactNo = iAppDeviceContactapplistRelativeService.getBy7DdayData(fingerprint, userId, 1);

        if (StringUtils.isBlank(contactNo)) {
            String applyNo = IdUtils.reqId();
            //通讯录是否为空
            List<ApplyContacts> contactsUser = getContacts(dataJson, applyNo, userId, appVersion);
            if (Func.isEmpty(iDeviceContactsService)) {
                throw new BusinessException(RspEnmu.PARAM_CANNOT_NULL);
            }
            long start = System.currentTimeMillis();
            saveContactsDBV228(userId,custNo, contactsUser, applyNo, fingerprint);
            long end = System.currentTimeMillis();
            log.info("通讯录入库耗时：" + (end - start) + " ms");
        }
    }

    public void saveContactsDBV228(String userId,String custNo, List<ApplyContacts> contactsUser, String applyNo, String fingerprint) {
        QueryWrapper<CustContactsRelative> applyContactsQueryWrapper = new QueryWrapper<>();
        applyContactsQueryWrapper.eq("cust_no", userId).last("limit 1");
        CustContactsRelative one = custContactsRelativeMapper.selectOne(applyContactsQueryWrapper);
        if (one == null || StringUtils.isBlank(one.getContactsTableName())) {
            String tableName = iDeviceContactsService.getTableName(fingerprint);
            List<DeviceContacts> contactsDevice = userToDeviceContacts(contactsUser, fingerprint);
            iDeviceContactsService.batchSaveContactsTableName(contactsDevice, tableName);
        } else {
            //保存通讯录
            iApplyContactsService.batchSaveContactsTableName(contactsUser, one.getContactsTableName());
        }

        insertDeviceUser(userId, fingerprint);
        insertRelation(userId, applyNo, fingerprint);

        premiseService.deviceRulePremise(custNo,applyNo,"contactsFlag");
//        RulePremiseVo rulePremiseVo = RulePremiseVo.builder().custNo(custNo).userId(userId).serialNo(applyNo).fingerprint(fingerprint).build();
//        premiseService.rulePremiseV228(rulePremiseVo);
    }

    private void insertRelation(String userId, String applyNo, String fingerprint) {
        AppDeviceContactapplistRelative appDeviceContactapplistRelative = new AppDeviceContactapplistRelative();
        appDeviceContactapplistRelative.setRelativeNo(applyNo);
        appDeviceContactapplistRelative.setFingerprint(fingerprint);
        appDeviceContactapplistRelative.setType(1);
        appDeviceContactapplistRelative.setUserId(userId);
        iAppDeviceContactapplistRelativeService.insertAppDeviceContactapplistRelative(appDeviceContactapplistRelative);
    }

    private void insertDeviceUser(String userId, String fingerprint) {
        DeviceUser deviceUser = new DeviceUser();
        deviceUser.setDeviceId(fingerprint);
        deviceUser.setUserId(userId);
        iDeviceUserService.insertDeviceUser(deviceUser);
    }


    public List<DeviceContacts> userToDeviceContacts(List<ApplyContacts> contactsUser, String fingerprint) {
        List<DeviceContacts> list = new ArrayList<>();
        for (int i = 0; i < contactsUser.size(); i++) {
            ApplyContacts applyContacts = contactsUser.get(i);
            DeviceContacts deviceContacts = new DeviceContacts();
            deviceContacts.setDeviceId(fingerprint);
            deviceContacts.setApplyNo(applyContacts.getApplyNo());
            deviceContacts.setCallName(applyContacts.getCallName());
            deviceContacts.setPhone(applyContacts.getPhone());
            list.add(deviceContacts);
        }
        return list;
    }

    public void saveContactsDB(JSONObject dataJson, String applyNo, String userId, String custNo, String appVersion) {
        //通讯录是否为空
        List<ApplyContacts> contacts = getContacts(dataJson, applyNo, userId, appVersion);
        if (Func.isEmpty(contacts)) {
            throw new BusinessException(RspEnmu.PARAM_CANNOT_NULL);
        }

        String tableName = iApplyContactsService.getTableName(userId);
        String actionType = dataJson.getString("actionType");

        //设备指纹是否一致
        String sourceFingerprint = iAppDeviceInfoService.getDeviceIdByUserId(userId, DateUtils.getNowDate());
        boolean consistent = loanRule.fingerprintsSame(sourceFingerprint, applyNo, custNo);
        log.info("设备指纹是否一致，sourceFingerprint:{}", sourceFingerprint);

        //授信 & 设备指纹不一致｜7天内不存在 --> 新增
        if (BizConstants.RULE_TYPE_APPLY.equals(actionType) && (!consistent || iApplyContactsService.getCntContactsNum(tableName, userId, applyNo) == 0)) {
            if (StringUtils.isNotBlank(tableName)) {
                iApplyContactsService.batchSaveContactsTableName(contacts, tableName);
            } else {
                String devicetTableName = iDeviceContactsService.getTableName(sourceFingerprint);
                List<DeviceContacts> deviceContacts = userToDeviceContacts(contacts, sourceFingerprint);
                //新增DeviceUser -- 修复
                insertDeviceUser(userId, sourceFingerprint);
                insertRelation(userId, applyNo, sourceFingerprint);
                iDeviceContactsService.batchSaveContactsTableName(deviceContacts, devicetTableName);
            }
        }
        //提现   天内是否已经存储通讯录 不存在->新增
        if (BizConstants.RULE_TYPE_LOAN.equals(actionType) && (!consistent || Func.isEmpty(iApplyContactsService.get7DaysContactsCount(tableName, userId)))) {
            if (StringUtils.isNotBlank(tableName)) {
                iApplyContactsService.batchSaveContactsTableName(contacts, tableName);
            } else {
                String devicetTableName = iDeviceContactsService.getTableName(sourceFingerprint);
                List<DeviceContacts> deviceContacts = userToDeviceContacts(contacts, sourceFingerprint);
                //新增DeviceUser -- 修复
                insertDeviceUser(userId, sourceFingerprint);
                insertRelation(userId, applyNo, sourceFingerprint);
                iDeviceContactsService.batchSaveContactsTableName(deviceContacts, devicetTableName);
            }
        }

        if (Func.isEmpty(sourceFingerprint)) {
            sourceFingerprint = "";
        }
        RulePremiseVo rulePremiseVo = RulePremiseVo.builder().custNo(custNo).type(actionType).serialNo(applyNo).fingerprint(sourceFingerprint.toString()).build();
        premiseService.rulePremise(rulePremiseVo, "contactsFlag");
    }

    public List<ApplyContacts> getContacts(JSONObject dataJson, String applyNo, String custNo, String appVersion) {
        String actionType = dataJson.getString("actionType");
        List<ApplyContacts> contactsList = new ArrayList<>();
        String batchNo = DateFormatUtils.format(new Date(), "yyyyMMddHHmmss");

        //2.3.1开始解压缩
        String appStr = dataJson.getString("bookList");
        if (VersionUtils.compareVersion(appVersion, "2.3.1") >= 0) {
            appStr = CompressUtils.unCompress(appStr);
        }
        JSONArray dataJsonArr = JSONArray.parseArray(appStr);
//        JSONArray dataJsonArr = dataJson.getJSONArray("bookList");

        for (int i = 0; i < dataJsonArr.size(); i++) {
            JSONObject tempObject = dataJsonArr.getJSONObject(i);
            if (Func.isEmpty(tempObject.get("phone"))) {
                continue;
            }

            String phoneNumber = formatPhone(tempObject.get("phone").toString());

            String callName = "";
            if (Func.isEmpty(tempObject.get("callName"))) {
                callName = phoneNumber;
            } else {
                callName = StringUtils.removeNonBmpUnicodes(tempObject.get("callName").toString());
            }

            ApplyContacts applyContacts = new ApplyContacts();
            applyContacts.setCustNo(custNo);
            applyContacts.setBatchNo(batchNo);
            applyContacts.setApplyNo(applyNo);
            applyContacts.setState(UserConstants.NORMAL);
            applyContacts.setCreateTime(new Date());
            applyContacts.setActionType(actionType);
            applyContacts.setCallName(Func.filterEmoji(callName));
            applyContacts.setPhone(phoneNumber);
            applyContacts.setCountryCode(Func.isNotEmpty(tempObject.get("countryCode")) ? tempObject.get("countryCode").toString() : null);
            //超过字段长度
            if (phoneNumber.length() > 20 || callName.length() > 50) {
                log.info("通讯录授权字段长度超出phoneNumber:{},CallName{}", phoneNumber, callName);
                continue;
            }
            contactsList.add(applyContacts);
        }

        if (contactsList.size() == 0) {
            log.info("通讯录授权记录为0，actionType:{},No:{}", actionType, applyNo);
            return null;
        }
        return contactsList;
    }

    public String formatPhone(String phoneNumber) {
        return PhoneUtil.formatPhone(phoneNumber);
    }


    //更新用户积分
    private void updateUserScore(long userId, String type, Long score) {
        AppUserScore appUserScore = new AppUserScore();
        appUserScore.setUserId(userId);
        appUserScore.setType(type);
        appUserScore.setState(UserConstants.NORMAL);

        if (REGISTER_ACTION.equals(type)) {
            Date now = new Date();
            String yearStr = DateFormatUtils.format(now, "yyyy");
            int yearInt = Integer.parseInt(yearStr) - 2020;
            String scoreStr = DateFormatUtils.format(now, "MdHHmmss");
            scoreStr = yearInt + scoreStr;
            appUserScore.setScore(Long.parseLong(scoreStr));
        } else {
            if (null != score) {
                appUserScore.setScore(score);
            } else {
                appUserScore.setScore(0L);
            }
        }
        appUserScoreService.insertAppUserScore(appUserScore);
    }


}
